package com.mk.cloud.pt.controller.app;

import act.Act;
import act.apidoc.Description;
import act.controller.Controller;
import act.inject.DefaultValue;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mk.cloud.common.config.AppConfig;
import com.mk.cloud.common.domain.*;
import com.mk.cloud.common.enums.ErrorCode;
import com.mk.cloud.common.enums.GlobalValues;
import com.mk.cloud.common.exception.UserException;
import com.mk.cloud.common.interceptor.ITransacte;
import com.mk.cloud.common.interceptor.header.HeaderService;
import com.mk.cloud.common.interceptor.header.IHLogin;
import com.mk.cloud.common.util.DateUtils;
import com.mk.cloud.common.util.ResUtils;
import com.mk.cloud.common.util.S2;
import com.mk.cloud.pt.service.app.PCompanyService;
import com.mk.cloud.pt.service.app.RewardService;
import com.mk.cloud.union.SybConstants;
import com.mk.cloud.union.SybPayService;
import com.mk.cloud.union.SybUtil;
import com.mk.cloud.union.WechatUtil;
import org.beetl.sql.core.engine.PageQuery;
import org.osgl.http.H;
import org.osgl.mvc.annotation.GetAction;
import org.osgl.mvc.annotation.PostAction;
import org.osgl.mvc.annotation.With;
import org.osgl.util.S;

import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;

@Controller("app/order")
public class POrderController extends HeaderService {
    private final String notify_url = "/api/app/order/payNotify.json";

    @Inject
    private SybPayService sybPayService;
    @Inject
    private PCompanyService pCompanyService;

    @Inject
    private POrder.Mapper pOrderMapper;
    @Inject
    private POrderFlow.Mapper pOrderFlowMapper;
    @Inject
    private PUser.Mapper pUserMapper;

    @Inject
    private PBuyerAddress.Mapper pBuyerAddressMapper;

    @Inject
    private PProduct.Mapper pProductMapper;
    @Inject
    private PTeamAreaArea.Mapper pTeamAreaAreaMapper;

    @Inject
    private RewardService rewardService;

    @Description("下单接口")
    @PostAction("addOrder.json")
    @With({IHLogin.class, ITransacte.class})
    public String addOrder(
            @Description("pdid商品id") String pdid,
            @Description("gbid地址id") String gbid,
            @Description("买家留言") String comment
    ){
        //TODO (1)下单限制:新店体验产品,爆款类商品 只能各下一个单

        POrder pOrder = pOrderMapper.selectOnceOrder(me.getFuserid(),pdid);
        if(pOrder!=null){
            if(S.eq(GlobalValues.ORDER_STATE_1.value(),pOrder.getOrderstate())){
                return ResUtils.FAIL(ErrorCode.E301009);
            }
            if(S.eq(GlobalValues.ORDER_STATE_2.value(),pOrder.getOrderstate())
                    ||S.eq(GlobalValues.ORDER_STATE_3.value(),pOrder.getOrderstate())
                    ){
                return ResUtils.FAIL(ErrorCode.E301010);
            }
        }
//        Integer orderNumber = pOrderMapper.countOrderNumber(me.getFuserid(),pdid);
//        if(orderNumber>0){
//            throw new UserException("您已经下单,请到订单列表继续操作");
//        }
        //(2) 活动期数限制(如何处理)
        PBuyerAddress address = pBuyerAddressMapper.single(gbid);
        PProduct product = pProductMapper.single(pdid);
        POrder order = new POrder();
        String orderid = S2.buildOrderId("PO");
        order.setOrderid(orderid);
        order.setFuserid(me.getFuserid());
        order.setOrderstate(GlobalValues.ORDER_STATE_1.value());
        order.setOrderamount(product.getSaleprice());
        order.setShopname(address.getShopname());
        order.setUnderdate(DateUtils.getTimeNow());
        order.setRecipients(address.getGbcontacts());
        order.setPhone(address.getGbphone());
        order.setProvince(address.getGbprovincename());
        order.setCity(address.getGbcityname());
        order.setCitycode(address.getGbcitycode());
        order.setArea(address.getGbareaname());
        order.setAddress(address.getGbaddress());
        order.setBuyercomment(comment);
        order.setPdid(pdid);
        order.setCoid(me.getCoid());
        order.setPayid(S2.buildOrderId("PAY"));

        order.setPdname(product.getPdname());
        Map<String,String> pay = getPay(order);
        order.setWechatpayorder(JSON.toJSONString(pay));
        pOrderMapper.insert(order);

        String payinfo = pay.get("payinfo");
        Map payinfoObj = JSON.parseObject(payinfo,Map.class);
        payinfoObj.put("orderid",order.getOrderid());
        return ResUtils.OK(payinfoObj);
    }

    @Description("重新支付接口")
    @PostAction("rePay.json")
    @With({IHLogin.class, ITransacte.class})
    public String rePay(
            String orderid
    ){
        POrder order = pOrderMapper.single(orderid);
        if(order==null) {
            throw new UserException("该订单不存在,请刷新");
        }
        if(S.eq(order.getOrderstate(),GlobalValues.ORDER_STATE_2.value())||S.eq(order.getOrderstate(),GlobalValues.ORDER_STATE_3.value())){
            throw new UserException("该订单已经付款,无需重复付款");
        }
        if(S.eq(order.getOrderstate(),GlobalValues.ORDER_STATE_1.value())){
            try {
                Map<String,String> wechatOrder = JSON.parseObject(order.getWechatpayorder(),Map.class);
                Map<String,String> result = sybPayService.query(pCompanyService.getCompanyByCoid(me.getCoid()).getPCoconfig(),"",wechatOrder.get("trxid"));
                System.out.println(JSON.toJSONString(result));
                if(S.eq(result.get("retcode"),"SUCCESS")){
                    if(S.eq(result.get("trxstatus"),"0000")){
                        payOrder(order.getPayid(),JSON.toJSONString(result));
                        return ResUtils.FAIL(ErrorCode.E301008);
                    }else{
//                        if(result.get("trxstatus").indexOf("3")==0){//交易失败,则重新支付
                        if(S.isNotBlank(order.getWechatpayorder())){
                            String payinfo = wechatOrder.get("payinfo");
                            Map payinfoObj = JSON.parseObject(payinfo,Map.class);
                            payinfoObj.put("orderid",order.getOrderid());
                            return ResUtils.OK(payinfoObj);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ResUtils.OK();//TODO 还未处理判定是否已经支付
    }



    @PostAction("pay.json")
    public Map<String,String> getPay(POrder order){
//        POrder order = pOrderMapper.single(orderid);
        PUser user = pUserMapper.single(order.getFuserid());
        try {
            Map<String,String> result = sybPayService.pay(pCompanyService.getCompanyByCoid(me.getCoid()).getPCoconfig(),order.getOrderamount().multiply(new BigDecimal("100")).intValue(),
                    order.getPayid(),
                    "W06",//小程序支付
                    order.getPdname(),
                    order.getOrderid(),
                    user.getOpenid(),
//                    "",
                    AppConfig.miniapp.basepath.toString()+notify_url,
                    "" );
           return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new UserException(e.getMessage());
        }
    }

    @PostAction("payNotify.json")
    public String payNotify(){
        Map<String, String[]> result = context.allParams();
        System.out.println("支付回调:::::结果参数::::"+JSON.toJSONString(result));
        if(result.get("outtrxid")!=null){
            payOrder(result.get("outtrxid")[0],JSON.toJSONString(result));
            return "success";
        }else{
            return "fail";
        }
    }

    @Description("支付接口")
    @PostAction("payOrder.json")
    @With({IHLogin.class, ITransacte.class})
    public String payOrder(
            @Description("orderid订单payid") String payid,
            String params
    ){
        POrder pOrder = new POrder();
        pOrder.setPayid(payid);
        POrder order = pOrderMapper.templateOne(pOrder);
        //订单状态为改变才执行
        if(!S.eq(order.getOrderstate(),GlobalValues.ORDER_STATE_1.value())){
            return "fail";
        }
        order.setOrderstate(GlobalValues.ORDER_STATE_2.value());
        order.setPaydate(DateUtils.getTimeNow());
        pOrderMapper.updateTemplateById(order);

        //region 增加流水 开始
        POrderFlow orderFlow = new POrderFlow();
        orderFlow.setPayid(payid);
        orderFlow.setAllparams(params);
        orderFlow.setCoid(order.getCoid());
        orderFlow.setCreatetime(DateUtils.getTimeNow());
        orderFlow.setFuserid(order.getFuserid());
//        orderFlow.setOpenid();
        orderFlow.setOfid(S2.UUID());
        pOrderFlowMapper.insert(orderFlow);
        //endregion 结束
        PUser pUser = pUserMapper.single(order.getFuserid());//推广人相关信息
        if(S.neq(pUser.getPlevel(),GlobalValues.PLEVEL_1.value())){
            PUser buyuser = pUserMapper.single(order.getFuserid());
            if(S.isBlank(buyuser.getPfuserid())){//用户没有推广人才执行其他
                //region 判断分享人是否有分享资格
                String sharedid = Act.cache().get(order.getFuserid());
                if(S.isNotBlank(sharedid)){//如果缓存中有对应的用户推广信息,则使用缓存中的
                    buyuser.setPfuserid2(sharedid);
                }
                PUser fatherUser = pUserMapper.single(buyuser.getPfuserid2());
                if(fatherUser!=null){
                    String taid = fatherUser.getTaid();
                    if(S.eq(fatherUser.getPlevel(),GlobalValues.PLEVEL_2.value())){
                        PUser partnerUser = pUserMapper.single(fatherUser.getPfuserid());//合伙人
                        taid = partnerUser.getTaid();
                    }
                    PTeamAreaArea areaArea = new PTeamAreaArea();
                    areaArea.setTaid(taid);
                    areaArea.setCoid(buyuser.getCoid());
                    areaArea.setAreacode(order.getCitycode());
                    long area = pTeamAreaAreaMapper.templateCount(areaArea);
                    if(area>0){
                        //(1)判断是否需要建立推广关系;//之前已经判断好了该推广是否有效,只是未具体建立关系
                        PUser user = new PUser();
                        user.setFuserid(buyuser.getFuserid());
                        user.setPfuserid(buyuser.getPfuserid2());
                        user.setFuserid1(buyuser.getPfuserid2()); //上级作为一级级
                        user.setTaid(taid);
                        if(S.eq(fatherUser.getPlevel(),GlobalValues.PLEVEL_2.value())){
                            user.setPlevel(GlobalValues.PLEVEL_3.value());
                            user.setFuserid2(fatherUser.getFuserid1()); //上上级作为二级
                        }else if(S.eq(fatherUser.getPlevel(),GlobalValues.PLEVEL_1.value())){
                            user.setPlevel(GlobalValues.PLEVEL_2.value());
                        }
                        pUser = user;//pUser中没有推广人信息,需要更新成最新的推广人关系信息
                        PProduct product = pProductMapper.single(order.getPdid());
                        if(S.eq(product.getPdtype(),GlobalValues.PD_TYPE_0.value())){//购买的是新店体验,才可以更新到推店关系中
                            pUserMapper.updateTemplateById(user);
                        }
                        pUser.setCoid(order.getCoid());
                    }
                }
            }
            //endregion 判断分享人是否有分享资格

            //(2)判断是否要给相关的推广人推广奖励
            rewardService.reward(order,pUser);
        }
        return ResUtils.OK(order);
    }


    @Description("小程序动态菜单--小程序动态菜单列表")
    @GetAction("list.json")
    @With(IHLogin.class)
    public String pProductList(
            H.Session session,
            @Description("当前第几页") @DefaultValue("1") Integer currentPage,
            @Description("每页多少条") @DefaultValue("100") Integer pageSize

    ) {
        PageQuery<PWechatMenus> query = new PageQuery<>();
        query.setPageSize(pageSize);
        query.setPageNumber(currentPage);
        Map<String, Object> map = new HashMap<>();
        map.put("isshow", GlobalValues.FLAG_YES.value());
        map.put("coid", me.getCoid());
        query.setParas(map);
        pOrderMapper.getSQLManager().pageQuery("pWechatMenus.select_wechat_menus_list", PWechatMenus.class, query);
        return ResUtils.OK(query.getList());
    }


    @Description("小程序动态菜单--小程序动态菜单详情")
    @GetAction("get.json")
    public String getPWechatMenus(@Description("小程序动态菜单id") String sid) {
        if (S.isEmpty(sid)) {
            return ResUtils.OK(new PWechatMenus());
        }
        return ResUtils.OK(pOrderMapper.single(sid));
    }

    @Description("我的订单列表")
    @With(IHLogin.class)
    @GetAction("myorders.json")
    public String pOrderList(
            @Description("当前第几页") @NotNull Integer page,
            @Description("每页多少条") @DefaultValue("15") Integer size

    ) {
        PageQuery<POrder> query = new PageQuery<>();
        query.setPageSize(size);
        query.setPageNumber(page);
        Map<String, Object> map = new HashMap<>();
        map.put("fuserid", me.getFuserid());
        map.put("coid", me.getCoid());
        query.setParas(map);
        //此处的sql是三个sql
        pOrderMapper.getSQLManager().pageQuery("pOrder.select_order_page_list", POrder.class, query);
        return ResUtils.OK(query.getList());
    }

    @Description("我的订单详情")
    @With(IHLogin.class)
    @GetAction("myorderDetail.json")
    public String pOrderDetail(
            @Description("订单id") @NotNull String orderid
    ) {
        return ResUtils.OK(pOrderMapper.orderDetail(orderid));
    }

    @Description("我的订单详情")
    @With(IHLogin.class)
    @GetAction("pOrders.json")
    public String pOrders(
            @Description("商品类型 pdtype 0新店体验,3爆品体验") @NotNull String pdtype
    ) {
        List<POrder> list = pOrderMapper.selectOrdersSubUserid(me.getFuserid(),pdtype);
//        List<POrder> list = pOrderMapper.selectOrdersSubUserid("HGBQ9J",pdtype);
        return ResUtils.OK(list);
    }

    @Description("分享结果统计")
    @With(IHLogin.class)
    @GetAction("shareCount.json")
    public String shareCount() {
        Map<String,Integer> map = new HashMap<>();
        map.put("shopnum",pOrderMapper.selectCountNum(me.getFuserid()));
        map.put("numtop",pOrderMapper.selectNumberInTeamarea(me.getFuserid(),me.getTaid()));
        return ResUtils.OK(map);
    }

    @Description("分享结果统计")
    @With(IHLogin.class)
    @GetAction("shareCountCenter.json")
    public String shareCountCenter() {
//        Map<String,Integer> map = new HashMap<>();
//        map.put("shopnum",pOrderMapper.selectCountNum(me.getFuserid()));
//        map.put("numtop",pOrderMapper.selectNumberInTeamarea(me.getFuserid(),me.getTaid()));
        return ResUtils.OK(pOrderMapper.selectCountNum(me.getFuserid()));
    }

}
